#include <string.h>
#include <stdio.h>
#include <sys/syscall.h>  
#include <unistd.h>

#include "HeaderParse.h"
#include "Global.h"

HeaderParse::HeaderParse(const char *header):
m_headerlinelen(0),
m_UrlValuelen(0)
{
    int i = 0;

    for(i = 0; i < URLVALUE_SIZE; i++)
    {
        bzero(m_UrlValue[i].key, KEY_SIZE);
        bzero(m_UrlValue[i].value, VALUE_SIZE);
    }

    for(i = 0; i < HEADERMAXLINE; i++)
    {
        bzero(m_UserInfo[i].key, KEY_SIZE);
        bzero(m_UserInfo[i].value, VALUE_SIZE);
    }

    char *pLine = m_header;
    memcpy(m_header, header, HEADER_SIZE);
    for(i=0; i<HEADER_SIZE; i++)
    {
        if(m_header[i] == '\r')
        {
             m_header[i] = '\0';
             if(m_header[i+2] == '\r')
                break;
        }
    }

    for(int Line = 0; Line<HEADERMAXLINE; Line++)
    {
        if(Line == 0)
        {
                //get method
                int index=0;
                i = 0;
                while(m_header[index] != ' ')
                {
                    m_Method[i] = m_header[index];
                    index++;
                    i++;
                }
                index++;
                m_Method[i] = '\0';

                //get path
                i = 0;
                memcpy(m_Path, FILEPATH, sizeof(FILEPATH));
                i = i + strlen(FILEPATH);
                while(m_header[index] != ' ')
                {
                    m_Path[i] = m_header[index];
                    i++;
                    index++;
                }
                index++;
                m_Path[i] = '\0';

                //get url value
                i = 0;
                bool ok = false;
                while(m_Path[i] != '\0')
                {
                    if(m_Path[i] == '?')
                    {
                       m_Path[i] = '\0'; 
                       i++;
                       ok = true;
                       int k=0,v=0,l=0,key=1;
                       while(m_Path[i] != '\0')
                       {
                            if(m_Path[i] == '=')
                            {
                                key = 0;
                                k = 0;
                                v = 0;
                            }
                            else if(m_Path[i] == '&')
                            {
                                key = 1;
                                l++;
                                k = 0;
                                v = 0;
                            }
                            else
                            {
                                if(key)
                                {
                                    m_UrlValue[l].key[k] = m_Path[i];
                                    k++;
                                }
                                else
                                {
                                    m_UrlValue[l].value[v] = m_Path[i];
                                    v++;
                                }
                            }
                            i++;
                       }
                       m_UrlValuelen = l+1;
                       break;
                    }
                    i++;
                }

                char buf[100];
                strcpy(buf,FILEPATH);
                strcat(buf,"/");
                if(0 == strcmp(m_Path, buf))
                {
                    strcat(m_Path, DEFAULT_PAGE);
                }

                i = (int)strlen(pLine);
                pLine = pLine + i + 2;
        }
        else
        {
            int Linelen = (int)strlen(pLine); 
            if(*pLine == '\r')  //last line
            {
                break;
            }

            i = 0;
            while(pLine[i] != ':')
            {
                m_UserInfo[Line-1].key[i] = pLine[i]; 
                i++;
            }
            m_UserInfo[Line-1].key[i] = '\0'; 
            i++;

            int j = 0;
            while(pLine[i] != '\0')
            {
                m_UserInfo[Line-1].value[j] = pLine[i];
                i++;
                j++;
            }
            m_UserInfo[Line-1].value[j] = '\0';

            m_headerlinelen++;
            pLine = pLine + Linelen + 2; //pLine -> next line
        }
    }
}

HeaderParse::~HeaderParse()
{
    
}

void 
HeaderParse::getMethod(char *method)
{
    memcpy(method, m_Method, METHOD_SIZE);
}

void 
HeaderParse::getPath(char *path)
{
    strcpy(path, m_Path);
}

void 
HeaderParse::printHeader()
{
    printf("********************header info********************\n");
    for(int i=0; i<m_headerlinelen; i++)
    {
        printf("[tid:%d]\tindex:%d\tkey:%s\tvalue:%s\n",gettid,i,m_UserInfo[i].key,m_UserInfo[i].value);
    }
    printf("***************get method variable info***************\n");
    for(int i=0; i<m_UrlValuelen; i++)
    {
        printf("[tid:%d]\tindex:%d\tkey:%s\tvalue:%s\n",gettid,i,m_UrlValue[i].key,m_UrlValue[i].value);
    }
}

//example:
/*
    char userAgent[100];
    getValueByKey("User-Agent",userAgent);
then:
    userAgent = Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0)
*/

void 
HeaderParse::getValueByKey(const char *key, char *value)
{
    for(int i=0; i<m_headerlinelen; i++)
    {
        if(0 == strcmp(key, m_UserInfo[i].key))
        {
            strcpy(value, m_UserInfo[i].value+1); //add 1 for Remove the first space
            break;
        }
    }
}

void 
HeaderParse::getUrlValueByKey(const char *key, char *value)
{
    for(int i=0; i<m_UrlValuelen; i++)
    {
        if(0 == strcmp(key, m_UrlValue[i].key))
        {
            strcpy(value, m_UrlValue[i].value); //add 1 for Remove the first space
            break;
        }
    }
}